package com.by.common.fileService.impl;

import com.by.common.fileService.FileUploadService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletContext;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.UUID;

/**
 * @author Ye QS
 * @version 0.1
 * @className FileUploadServiceImpl
 * @description
 * @date 2024/9/17 9:50
 * @since jdk11
 */
@Service
public class FileUploadServiceImpl implements FileUploadService {
    /**
     * 上传文件的方法
     *
     * @param file 待上传的文件，类型为 MultipartFile，允许在表单中上传文件
     * @param type 文件类型，用于可能的文件分类或权限控制
     * @return 上传文件在服务器上的绝对路径
     * @throws IOException 如果文件 IO 操作中出现错误
     */
    @Override
    public String uploadFile(MultipartFile file, String type) throws IOException {
        // 获取文件部分的名称（即表单中的 name 属性）
        String name = file.getName();
        System.out.println(name);

        // 获取上传文件的原始文件名
        String originalFilename = file.getOriginalFilename();
        System.out.println(originalFilename);

        // 从 HTTP 请求中获取 ServletContext 对象
        ServletContext application = null; // 这里需要从某个地方注入，因为 Service 层没有直接访问 HttpServletRequest 的能力

        // 获取服务器上的实际路径，指向 "upload" 目录
        String realPath = application.getRealPath("/upload");

        // 创建一个 File 对象来表示上传目录
        File fileDir = new File(realPath);

        // 如果上传目录不存在，则创建它
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }

        // 生成一个唯一的文件名，以避免文件覆盖问题
        String uniqueFileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));

        // 创建一个 File 对象来表示目标文件（即上传文件）
        File destFile = new File(fileDir.getAbsolutePath() + "/" + uniqueFileName);

        // 使用 BufferedOutputStream 包装输出流以提高写入效率
        try (BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(destFile.toPath()));
             BufferedInputStream bis = new BufferedInputStream(file.getInputStream())) {

            // 定义缓冲区大小为 10 KB
            byte[] bytes = new byte[1024 * 10];

            int readCount = 0;
            while ((readCount = bis.read(bytes)) != -1) {
                // 将从输入流读取的数据写入到输出流
                bos.write(bytes, 0, readCount);
            }
        }

        // 返回文件的存储位置
        return destFile.getAbsolutePath();
    }
}
